<?php
/**
 * vanephp web framework
 * 角色访问控制的调度器类
 *
 * @author aray <ofree@qq.com>
 * @link http://www.vanephp.com/
 * @copyright Copyright &copy; 2010 aray
 * @license http://www.vanephp.com/license
 * @package dispatcher
 */

if ( ! defined ( 'INVANE' ) )
	exit ( '!' );

vane::load ( 'vane_dispatcher_simple' );
/**
 * 使用了角色访问控制的调度器
 * @author aray
 *
 */
class vane_dispatcher_auth extends vane_dispatcher_simple {
	private $act = array ();
	
	/**
	 * RBAC验证
	 */
	public function check ( ) {
		$this->loadACT ( );
		
		if ( ! $this->act || ! is_array ( $this->act ) ) {
			trigger_error ( 'ACL没有任何定义', E_USER_ERROR );
		}
		
		$_user = dispatcher::getUser ( );
		$_role = dispatcher::getRole ( );
		
		# 默认阻止所有
		$auth = false;
		if ( isset ( $this->act[$this->controller] ) ) {
			switch ( $this->act[$this->controller] ) {
				# 匿名
				case 'rbac_all' :
					$auth = true;
					break;
				# 有权限
				case 'rbac_has_role' :
					if ( $_user ) {
						$auth = true;
					}
					break;
				# 没有权限
				case 'rbac_no_role' :
					if ( $_user ) {
						$auth = false;
					}
					break;
				# 特定权限
				default :
					if ( is_array ( $this->act[$this->controller] ) ) {
						if ( isset ( $this->act[$this->controller]['allow'] ) ) {
							switch ( $this->act[$this->controller]['allow'] ) {
								# 允许权限
								case 'rbac_all' :
									$auth = true;
									break;
								case 'rbac_has_role' :
									if ( $_user ) {
										$auth = true;
									}
									break;
								case 'rbac_no_role' :
									if ( $_user ) {
										$auth = false;
									} else {
										$auth = true;
									}
									break;
								default :
									$roles = explode ( ',', $this->act[$this->controller]['allow'] );
									foreach ( $roles as $r ) {
										if ( $this->checkRole ( $r ) ) {
											$auth = true;
											break;
										}
									}
							}
						}
						# 阻止权限
						if ( isset ( $this->act[$this->controller]['deny'] ) ) {
							switch ( $this->act[$this->controller]['deny'] ) {
								case 'rbac_all' :
									$auth = false;
									break;
								case 'rbac_has_role' :
									if ( $_user ) {
										$auth = false;
									}
									break;
								case 'rbac_no_role' :
									if ( $_user ) {
										$auth = true;
									} else {
										$auth = true;
									}
									break;
								default :
									$roles = explode ( ',', $this->act[$this->controller]['deny'] );
									foreach ( $roles as $r ) {
										if ( $this->checkRole ( $r ) ) {
											$auth = false;
											break;
										}
									}
							
							}
						}
						# 动作列表
						if ( isset ( $this->act[$this->controller]['actions'] ) && is_array ( $this->act[$this->controller]['actions'] ) && isset ( $this->act[$this->controller]['actions'][$this->action] ) ) {
							switch ( $this->act[$this->controller]['actions'][$this->action] ) {
								# 匿名
								case 'rbac_all' :
									$auth = true;
									break;
								# 有权限
								case 'rbac_has_role' :
									if ( $_user ) {
										$auth = true;
									}
									break;
								# 没有权限
								case 'rbac_no_role' :
									if ( $_user ) {
										$auth = false;
									} else {
										$auth = true;
									}
									break;
								# 
								default :
									if ( isset ( $this->act[$this->controller]['actions'][$this->action]['allow'] ) || isset ( $this->act[$this->controller]['actions'][$this->action]['deny'] ) ) {
										# 允许权限
										if ( isset ( $this->act[$this->controller]['actions'][$this->action]['allow'] ) ) {
											$roles = explode ( ',', $this->act[$this->controller]['actions'][$this->action]['allow'] );
											foreach ( $roles as $r ) {
												if ( $this->checkRole ( $r ) ) {
													$auth = true;
													break;
												}
											}
										}
										# 阻止权限
										if ( isset ( $this->act[$this->controller]['actions'][$this->action]['deny'] ) ) {
											$roles = explode ( ',', $this->act[$this->controller]['actions'][$this->action]['deny'] );
											foreach ( $roles as $r ) {
												if ( $this->checkRole ( $r ) ) {
													$auth = false;
													break;
												}
											}
										}
									} else {
										$roles = explode ( ',', $this->act[$this->controller]['actions'][$this->action] );
										foreach ( $roles as $r ) {
											if ( $this->checkRole ( $r ) ) {
												$auth = true;
												break;
											}
										}
									}
							}
						}
						return $auth;
					} else {
						$roles = explode ( ',', $this->act[$this->controller] );
						foreach ( $roles as $r ) {
							if ( $this->checkRole ( $r ) ) {
								$auth = true;
							}
						}
					}
			}
		}
		
		return $auth;
	}
	
	/**
	 * 验证用户是否为角色身份
	 * @param string $role		角色名称
	 */
	public function checkRole ( $role ) {
		$role = trim ( $role );
		$roles = dispatcher::getRole ( );
		if ( $roles && in_array ( $role, $roles ) ) {
			return true;
		}
		
		return false;
	}
	
	/**
	 * 加载ACT文件
	 */
	private function loadACT ( ) {
		$actFile = config::get ( 'act_file' );
		if ( $actFile == null )
			trigger_error ( "ACT访问控制表不存在", E_USER_ERROR );
		$this->act = vane::load ( $actFile );
	}
}